package tracks.client;

import tracks.client.map.IMapEventListener;
import tracks.client.map.MapController;
import tracks.client.map.MapEvent;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.event.MapRightClickHandler;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Tracksgwt implements EntryPoint, IMapEventListener {
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";

	/**
	 * Create a remote service proxy to talk to the server-side Greeting
	 * service.
	 */
	private final GreetingServiceAsync greetingService = GWT
			.create(GreetingService.class);

	/** Map controller */
	private MapController mapController;

	/** Google Map */
	private MapWidget map;

	/** Button to create route */
	private ToggleButton createRouteBtn;

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

		mapController = MapController.getInstance();

		// Panel that contains all. This is added directly to the root panel.
		HorizontalPanel bodyPanel = new HorizontalPanel();

		// Stack panel on the left.
		StackPanel leftStack = new StackPanel();

		// Panel that is used for creating routes on the map.
		ButtonHandler btnHandler = new ButtonHandler();
		VerticalPanel routeToolsPanel = new VerticalPanel();
		createRouteBtn = new ToggleButton();
		createRouteBtn.setText("Create Route");
		createRouteBtn.addClickHandler(btnHandler);
		routeToolsPanel.add(createRouteBtn);

		String text1 = "Lorem ipsum dolor sit amet...";
		String text2 = "Sed egestas, arcu nec accumsan...";
		String text3 = "Proin tristique, elit at blandit...";
		leftStack.add(routeToolsPanel, "Route", false);
		leftStack.add(new Label(text2), "Two", false);
		leftStack.add(new Label(text3), "Three", false);
		leftStack.setSize("200px", "500px");

		StackPanel rightStack = new StackPanel();
		rightStack.add(new Label(text1), "Four", false);
		rightStack.add(new Label(text2), "Five", false);
		rightStack.add(new Label(text3), "Six", false);
		rightStack.setSize("200px", "500px");

		// LatLng home = LatLng.newInstance(38.949, -104.784);
		// map.addOverlay(new Marker(home));
		// map
		// .getInfoWindow()
		// .open(
		// map.getCenter(),
		// new InfoWindowContent(
		// "Home of Scott, Kristen, London, Bailey, Cricket, and Elka"));
		MapHandler mapHandler = new MapHandler();
		map = mapController.getMap();
		map.setSize("700px", "500px");
		map.addControl(new LargeMapControl());
		map.addMapRightClickHandler(mapHandler);

		bodyPanel.add(leftStack);
		bodyPanel.add(map);
		bodyPanel.add(rightStack);

		// Add body panel to the root panel.
		RootPanel.get().add(bodyPanel);

		// final Button sendButton = new Button("Send");
		// final TextBox nameField = new TextBox();
		// nameField.setText("GWT User");
		//
		// // We can add style names to widgets
		// sendButton.addStyleName("sendButton");
		//
		// // Add the nameField and sendButton to the RootPanel
		// // Use RootPanel.get() to get the entire body element
		// RootPanel.get("nameFieldContainer").add(nameField);
		// RootPanel.get("sendButtonContainer").add(sendButton);
		//
		// // Focus the cursor on the name field when the app loads
		// nameField.setFocus(true);
		// nameField.selectAll();
		//
		// // Create the popup dialog box
		// final DialogBox dialogBox = new DialogBox();
		// dialogBox.setText("Remote Procedure Call");
		// dialogBox.setAnimationEnabled(true);
		// final Button closeButton = new Button("Close");
		// // We can set the id of a widget by accessing its Element
		// closeButton.getElement().setId("closeButton");
		// final Label textToServerLabel = new Label();
		// final HTML serverResponseLabel = new HTML();
		// VerticalPanel dialogVPanel = new VerticalPanel();
		// dialogVPanel.addStyleName("dialogVPanel");
		// dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
		// dialogVPanel.add(textToServerLabel);
		// dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
		// dialogVPanel.add(serverResponseLabel);
		// dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		// dialogVPanel.add(closeButton);
		// dialogBox.setWidget(dialogVPanel);
		//
		// // Add a handler to close the DialogBox
		// closeButton.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// dialogBox.hide();
		// sendButton.setEnabled(true);
		// sendButton.setFocus(true);
		// }
		// });
		//
		// // Create a handler for the sendButton and nameField
		// class MyHandler implements ClickHandler, KeyUpHandler {
		// /**
		// * Fired when the user clicks on the sendButton.
		// */
		// public void onClick(ClickEvent event) {
		// sendNameToServer();
		// }
		//
		// /**
		// * Fired when the user types in the nameField.
		// */
		// public void onKeyUp(KeyUpEvent event) {
		// if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
		// sendNameToServer();
		// }
		// }
		//
		// /**
		// * Send the name from the nameField to the server and wait for a
		// * response.
		// */
		// private void sendNameToServer() {
		// sendButton.setEnabled(false);
		// String textToServer = nameField.getText();
		// textToServerLabel.setText(textToServer);
		// serverResponseLabel.setText("");
		// greetingService.greetServer(textToServer,
		// new AsyncCallback<String>() {
		// public void onFailure(Throwable caught) {
		// // Show the RPC error message to the user
		// dialogBox
		// .setText("Remote Procedure Call - Failure");
		// serverResponseLabel
		// .addStyleName("serverResponseLabelError");
		// serverResponseLabel.setHTML(SERVER_ERROR);
		// dialogBox.center();
		// closeButton.setFocus(true);
		// }
		//
		// public void onSuccess(String result) {
		// dialogBox.setText("Remote Procedure Call");
		// serverResponseLabel
		// .removeStyleName("serverResponseLabelError");
		// serverResponseLabel.setHTML(result);
		// dialogBox.center();
		// closeButton.setFocus(true);
		// }
		// });
		// }
		// }
		//
		// // Add a handler to send the name to the server
		// MyHandler handler = new MyHandler();
		// sendButton.addClickHandler(handler);
		// nameField.addKeyUpHandler(handler);
	}

	/**
	 * Class that handles Google Map native map events.
	 */
	private class MapHandler implements MapRightClickHandler {
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.google.gwt.maps.client.event.MapRightClickHandler#onRightClick
		 * (com
		 * .google.gwt.maps.client.event.MapRightClickHandler.MapRightClickEvent
		 * )
		 */
		@Override
		public void onRightClick(MapRightClickEvent event) {
			Object source = event.getSource();
			if (source.equals(map)) {
				MapEvent mapEvent = new MapEvent();
				mapController.getMapEventNotifier().notifyListeners(mapEvent);
			}
		}
	}

	/**
	 * Class that listens for button events.
	 */
	private class ButtonHandler implements ClickHandler {
		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt
		 * .event.dom.client.ClickEvent)
		 */
		@Override
		public void onClick(ClickEvent event) {
			Object source = event.getSource();
			if (source.equals(createRouteBtn)) {
				boolean btnDown = createRouteBtn.isDown();
				if (btnDown) {
					mapController.getMapEventNotifier().addListener(
							Tracksgwt.this);
				} else {
					mapController.getMapEventNotifier().removeListener(
							Tracksgwt.this);
				}
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * tracks.client.map.IMapEventListener#notify(tracks.client.map.MapEvent)
	 */
	@Override
	public void notify(MapEvent mapEvent) {
		System.out.println("Tracksgwt notified of MapEvent.");
	}

}
